#include "vfx_components.h"

#include "math/math_core.h"
#include "graphics/graphics_util.h"
#include "script/scripthelper.h"
#include "script/write_lua.h"
#include "font/font_manager.h"
#include "dd/dd_man.h"
#include "util/mmgr.h"		    // Needs to come in early
#include "util/common_macros.h"		// macros
#include "util/log.h"		    // logging
#include "util/timer.h"		    // logging
#include <cassert>

using namespace vfx;


VFXGradients::VFXGradients()
{

}

VFXGradients::~VFXGradients()
{

}
void VFXGradients::Tick(float dt)
{
	for (int i=(int)(m_Gradients.size())-1; i>=0; i--)
	{
		Gradient* pGrad = m_Gradients[i];
		if (pGrad->Delay < 0)
		{
			pGrad->Prog.Tick(dt);
			if (pGrad->Prog.IsReady())
			{
				delete pGrad;
				m_Gradients.erase(m_Gradients.begin()+i);
			}
		} else
		{
			pGrad->Delay-=dt;
		}
	}
}

void VFXGradients::Render(const math::Vec2& Offset, float Scale)
{
	// infalling gradients
	for (unsigned int i=0; i<m_Gradients.size(); i++)
	{
		Gradient* pGrad = m_Gradients[i];
		if (pGrad->Delay >0) continue;
		float Size = (pGrad->From + ((pGrad->To-pGrad->From) * pGrad->Prog.GetProgress())) * Scale;
		m_Gradient.m_Pos= (m_Pos - Offset)*Scale;
		m_Gradient.m_Size.x = Size*2;
		m_Gradient.m_Size.y = Size*GraphicsUtil::W2H*2;
		m_Gradient.m_Additive = true;
		m_Gradient.RenderRotated();
	}
}





//////////////////////////////
VFXGodRays::VFXGodRays() :
	m_Radius(1.0f)
{
	m_Colors.AddColor(1, 1, 1, 0, 0);	// starts white hot
	m_Colors.AddColor(1, 1, 1, 1.0f, 0.2f);	// starts white hot
	m_Colors.AddColor(1, 1, 1, 0.2f, 0.9f);	// starts white hot
	m_Colors.AddColor(1, 1, 1, 0, 1.0f);	// shifts to yellow
	m_Colors.Recalc();	// force a recalculation
}
VFXGodRays::~VFXGodRays()
{
}

void	VFXGodRays::Tick(float dt)
{
	for (int i=(int)(m_GodRays.size())-1; i>=0; i--)
	{
		GodRay* pRay = m_GodRays[i];
		pRay->Prog.Tick(dt);
		pRay->Rot += pRay->RotSpeed*dt;
		if (pRay->Prog.IsReady())
		{
			delete pRay;
			m_GodRays.erase(m_GodRays.begin()+i);
		}
	}
}
void	VFXGodRays::Render(const math::Vec2& Offset, float Scale)
{
	if (m_GodRays.empty()) return;

	Graphics::Vertex2D*	VertA = Graphics::GetTempVert();
	int	Index = 0;
	math::Vec2	P = (m_Pos-Offset)*Scale;

	math::Vec2	uv1(0,0);
	math::Vec2	uv2(1,1);
	for (unsigned int i=0; i<m_GodRays.size(); i++)
	{
		GodRay* pRay = m_GodRays[i];
		math::Vec2	To;
		float t = pRay->Prog.GetProgress();
		COLOR c=m_Colors.GetColor(t);
		float	 Rad = (16.0f + (64.0f*t))*GraphicsUtil::InvW*Scale;
		To.x = cosf(pRay->Rot*DEG_TO_RAD) * pRay->Length * Scale;
		To.y = sinf(pRay->Rot*DEG_TO_RAD) * pRay->Length*GraphicsUtil::W2H* Scale;
		Index+=GraphicsUtil::FillLine(P, P+To, Rad, c, c, uv1, uv2, &VertA[Index]);
		assert(Index < Graphics::MAX_TEMP_VERT);
	}
	if (Index > 0)
	{
		m_GodRay.SetTexture();
		GetGraphics()->SetupAdditiveAlpha(true);
		GetGraphics()->DrawVertex2D(VertA, Index);
		GetGraphics()->SetupAdditiveAlpha(false);
	}

}
